package com.tian.library.permission

import android.annotation.SuppressLint
import android.app.Activity
import android.app.AppOpsManager
import android.app.NotificationManager
import android.content.Context
import android.content.ContextWrapper
import android.content.Intent
import android.content.pm.PackageManager
import android.os.Build
import android.os.Environment
import android.provider.Settings
import android.text.TextUtils
import androidx.fragment.app.FragmentActivity
import java.lang.reflect.InvocationTargetException
import kotlin.math.pow
import kotlin.random.Random

/**
 * @author tiansongtao, Email:tiansongtao@up366.com
 * @date 2020/12/10 19:50
 * 权限请求工具类
 */
internal object PermissionUtil {

    /**
     * 是否是 Android 11 及以上版本
     */
    fun isHigherAndroid11() = Build.VERSION.SDK_INT >= Build.VERSION_CODES.R

    /**
     * 是否是 Android 10 及以上版本
     */
    fun isHigherAndroid10() = Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q

    /**
     * 是否是 Android 8.0 及以上版本
     */
    fun isHigherAndroid9() = Build.VERSION.SDK_INT >= Build.VERSION_CODES.P



    /**
     * 是否是 Android 8.0 及以上版本
     */
    fun isHigherAndroid8() = Build.VERSION.SDK_INT >= Build.VERSION_CODES.O


    /**
     * 是否是 Android 7.0 及以上版本
     */
    fun isHigherAndroid7() = Build.VERSION.SDK_INT >= Build.VERSION_CODES.N


    /**
     * 是否是 Android 6.0 及以上版本
     */
    fun isHigherAndroid6() = Build.VERSION.SDK_INT >= Build.VERSION_CODES.M


    /**
     * 获取上下文中的 Activity 对象
     */
    fun getFragmentActivity(context: Context): FragmentActivity? {
        var result: Context? = context
        do {
            if (result is FragmentActivity) {
                return result
            } else if (result is ContextWrapper) {
                result = result.baseContext
            } else {
                result = null
            }
        } while (result != null)
        return null
    }

    /**
     * 处理和优化已经过时的权限
     */
    fun optimizeDeprecatedPermission(permissions: MutableSet<String>) {
        // 如果本次申请包含了 Android 11 存储权限
        if (permissions.contains(PermissionConstant.MANAGE_EXTERNAL_STORAGE)) {
            if (isHigherAndroid11()) {
                // 检测是否有旧版的存储权限，有的话直接抛出异常，请不要自己动态申请这两个权限
                permissions.remove(PermissionConstant.READ_EXTERNAL_STORAGE)
                permissions.remove(PermissionConstant.WRITE_EXTERNAL_STORAGE)
            } else {
                // 自动添加旧版的存储权限，因为旧版的系统不支持申请新版的存储权限
                permissions.remove(PermissionConstant.MANAGE_EXTERNAL_STORAGE)
                permissions.add(PermissionConstant.READ_EXTERNAL_STORAGE)
                permissions.add(PermissionConstant.WRITE_EXTERNAL_STORAGE)
            }
        }

        if (permissions.contains(PermissionConstant.ANSWER_PHONE_CALLS)) {
            if (!isHigherAndroid10() && !permissions.contains(PermissionConstant.PROCESS_OUTGOING_CALLS)) {
                permissions.remove(PermissionConstant.ANSWER_PHONE_CALLS)
                permissions.add(PermissionConstant.PROCESS_OUTGOING_CALLS)
            }
        }

        if (permissions.contains(PermissionConstant.ACTIVITY_RECOGNITION)) {
            if (!isHigherAndroid10() && !permissions.contains(PermissionConstant.BODY_SENSORS)) {
                // 自动添加传感器权限，因为这个权限是从 Android 10 开始才从传感器权限中剥离成独立权限
                permissions.remove(PermissionConstant.ACTIVITY_RECOGNITION)
                permissions.add(PermissionConstant.BODY_SENSORS)
            }
        }
    }

    /**
     * 判断某些权限是否全部被授予
     */
    fun isGrantedPermission(context: Context, permissions: MutableSet<String>): Boolean {
        // 如果是安卓 6.0 以下版本就默认授予
        if (!isHigherAndroid6()) {
            return true
        }

        for (permission in permissions) {
            if (!isGrantedPermission(context, permission)) {
                return false
            }
        }
        return true
    }


    /**
     * 判断某些权限是否全部被授予
     */
    fun isGrantedPermission(context: Context, permissions: Array<String>): Boolean {
        return isGrantedPermission(context, permissions.toMutableSet())

    }

    /**
     * 判断某个权限是否授予
     */
    fun isGrantedPermission(context: Context, permission: String): Boolean {
        // 如果是安卓 6.0 以下版本就默认授予
        if (!isHigherAndroid6()) {
            return true
        }

        // 检测存储权限
        if (TextUtils.equals(PermissionConstant.MANAGE_EXTERNAL_STORAGE, permission)) {
            return isGrantedStoragePermission(context)
        }

        // 检测安装权限
        if (TextUtils.equals(PermissionConstant.REQUEST_INSTALL_PACKAGES, permission)) {
            return isGrantedInstallPermission(context)
        }

        // 检测悬浮窗权限
        if (TextUtils.equals(PermissionConstant.SYSTEM_ALERT_WINDOW, permission)) {
            return isGrantedWindowPermission(context)
        }

        // 检测通知栏权限
        if (TextUtils.equals(PermissionConstant.NOTIFICATION_SERVICE, permission)) {
            return isGrantedNotifyPermission(context)
        }

        // 检测修改系统配置权限
        if (TextUtils.equals(PermissionConstant.WRITE_SETTINGS, permission)) {
            return isGrantedSettingPermission(context)
        }

        if (!isHigherAndroid10()) {
            // 检测 10.0 的三个新权限，如果当前版本不符合最低要求，那么就用旧权限进行检测

            // 检测 10.0 的三个新权限，如果当前版本不符合最低要求，那么就用旧权限进行检测
            if (TextUtils.equals(PermissionConstant.ACCESS_BACKGROUND_LOCATION,
                    permission) || TextUtils.equals(PermissionConstant.ACCESS_MEDIA_LOCATION,
                    permission)) {
                return true
            }

            if (TextUtils.equals(PermissionConstant.ACTIVITY_RECOGNITION, permission)) {
                return context.checkSelfPermission(PermissionConstant.BODY_SENSORS) == PackageManager.PERMISSION_GRANTED
            }
        }

        if (!isHigherAndroid8()) {
            // 检测 8.0 的两个新权限，如果当前版本不符合最低要求，那么就用旧权限进行检测
            if (TextUtils.equals(PermissionConstant.ANSWER_PHONE_CALLS, permission)) {
                return context.checkSelfPermission(PermissionConstant.PROCESS_OUTGOING_CALLS) == PackageManager.PERMISSION_GRANTED
            }

            if (TextUtils.equals(PermissionConstant.READ_PHONE_NUMBERS, permission)) {
                return context.checkSelfPermission(PermissionConstant.READ_PHONE_STATE) == PackageManager.PERMISSION_GRANTED
            }
        }


        return context.checkSelfPermission(permission) == PackageManager.PERMISSION_GRANTED
    }

    /**
     * 是否有存储权限
     */
    fun isGrantedStoragePermission(context: Context): Boolean {
        return if (isHigherAndroid11()) {
            Environment.isExternalStorageManager()
        } else {
            isGrantedPermission(context, PermissionConstant.Group.STORAGE)
        }
    }

    /**
     * 是否有安装权限
     */
    fun isGrantedInstallPermission(context: Context): Boolean {
        if (isHigherAndroid8()) {
            return context.packageManager.canRequestPackageInstalls()
        }
        return true
    }

    /**
     * 是否有悬浮窗权限
     */
    fun isGrantedWindowPermission(context: Context): Boolean {
        if (isHigherAndroid6()) {
            return Settings.canDrawOverlays(context)
        }
        return true
    }

    /**
     * 是否有通知栏权限
     */
    fun isGrantedNotifyPermission(context: Context): Boolean {
        if (isHigherAndroid7()) {
            return context.getSystemService(NotificationManager::class.java)
                .areNotificationsEnabled()
        }

        if (isHigherAndroid6()) {
            val appOps = context.getSystemService(Context.APP_OPS_SERVICE) as AppOpsManager
            try {
                val method = appOps.javaClass.getMethod("checkOpNoThrow",
                    Integer.TYPE,
                    Integer.TYPE,
                    String::class.java)
                val field = appOps.javaClass.getDeclaredField("OP_POST_NOTIFICATION")
                val value = field.get(Integer::class.java) as Integer
                return method.invoke(appOps,
                    value,
                    context.applicationInfo.uid,
                    context.packageName) as Int == AppOpsManager.MODE_ALLOWED
            } catch (ignored: NoSuchMethodException) {
                return true
            } catch (ignored: NoSuchFieldException) {
                return true
            } catch (ignored: InvocationTargetException) {
                return true
            } catch (ignored: IllegalAccessException) {
                return true
            } catch (ignored: RuntimeException) {
                return true
            }
        }
        return true
    }

    /**
     * 是否有系统设置权限
     */
    fun isGrantedSettingPermission(context: Context): Boolean {
        if (isHigherAndroid6()) {
            return Settings.System.canWrite(context)
        }
        return true
    }

    /**
     * 获得随机的 RequestCode
     */
    fun getRandomRequestCode(): Int {
        return Random.nextInt(2.0.pow(16.0).toInt())
    }

    fun containsSpecialPermission(permissions: MutableSet<String>): Boolean {
        if (permissions.isEmpty()) {
            return false
        }
        for (per in permissions) {
            if (isSpecialPermission(per)) {
                return true
            }
        }
        return false
    }

    /**
     * 判断某个权限是否是特殊权限
     */
    fun isSpecialPermission(permission: String): Boolean {
        return PermissionConstant.MANAGE_EXTERNAL_STORAGE == permission || PermissionConstant.REQUEST_INSTALL_PACKAGES == permission || PermissionConstant.SYSTEM_ALERT_WINDOW == permission || PermissionConstant.NOTIFICATION_SERVICE == permission || PermissionConstant.WRITE_SETTINGS == permission
    }

    @SuppressLint("QueryPermissionsNeeded")
    fun areActivityIntent(context: Context, intent: Intent): Boolean {
        return context.packageManager.queryIntentActivities(intent,
            PackageManager.MATCH_DEFAULT_ONLY).isNotEmpty()
    }

    /**
     * 获取某个权限的状态
     *
     * @return        已授权返回  {@link PackageManager#PERMISSION_GRANTED}
     *                未授权返回  {@link PackageManager#PERMISSION_DENIED}
     */
    fun getPermissionStatus(context: Context, permission: String): Int {
        return if (isGrantedPermission(context, permission)) {
            PackageManager.PERMISSION_GRANTED
        } else {
            PackageManager.PERMISSION_DENIED
        }
    }


    /**
     * 在权限组中检查是否有某个权限是否被永久拒绝
     *
     * @param activity              Activity对象
     * @param permissions            请求的权限
     */
    fun isPermissionPermanentDenied(activity: Activity, permissions: MutableSet<String>): Boolean {
        for (permission in permissions) {
            if (isPermissionPermanentDenied(activity, permission)) {
                return true
            }
        }
        return false
    }


    /**
     * 判断某个权限是否被永久拒绝
     *
     * @param activity              Activity对象
     * @param permission            请求的权限
     */
    fun isPermissionPermanentDenied(activity: Activity, permission: String): Boolean {
        if (!isHigherAndroid6()) {
            return false
        }

        // 特殊权限不算，本身申请方式和危险权限申请方式不同，因为没有永久拒绝的选项，所以这里返回 false
        if (isSpecialPermission(permission)) {
            return false
        }

        if (!isHigherAndroid10()) {
            // 检测 10.0 的三个新权限
            if (PermissionConstant.ACCESS_BACKGROUND_LOCATION == permission || PermissionConstant.ACCESS_MEDIA_LOCATION == permission) {
                return false
            }
            if (PermissionConstant.ACTIVITY_RECOGNITION == permission) {
                return activity.checkSelfPermission(PermissionConstant.BODY_SENSORS) == PackageManager.PERMISSION_DENIED &&
                        !activity.shouldShowRequestPermissionRationale(PermissionConstant.BODY_SENSORS)
            }
        }

        if (!isHigherAndroid9()) {
            // 检测 9.0 的一个新权限
            if (PermissionConstant.ACCEPT_HANDOVER == permission) {
                return false
            }
        }

        if (!isHigherAndroid8()) {
            // 检测 8.0 的两个新权限，如果当前版本不符合最低要求，那么就用旧权限进行检测
            if (PermissionConstant.ANSWER_PHONE_CALLS == permission) {
                return activity.checkSelfPermission(PermissionConstant.PROCESS_OUTGOING_CALLS) == PackageManager.PERMISSION_DENIED &&
                        !activity.shouldShowRequestPermissionRationale(PermissionConstant.PROCESS_OUTGOING_CALLS)
            }

            if (PermissionConstant.READ_PHONE_NUMBERS == permission) {
                return activity.checkSelfPermission(PermissionConstant.READ_PHONE_STATE) == PackageManager.PERMISSION_DENIED &&
                        !activity.shouldShowRequestPermissionRationale(PermissionConstant.READ_PHONE_STATE)
            }
        }

        return activity.checkSelfPermission(permission) == PackageManager.PERMISSION_DENIED &&
                !activity.shouldShowRequestPermissionRationale(permission)
    }

}